#include <bits/stdc++.h>
using namespace std;
//C++98     
/*缺点：对象所有权可以在多个指针转移，产生混乱*/
template <typename T>
class AutoPtr{
public:
    AutoPtr():m_data(nullptr){}
    AutoPtr(T* data):m_data(data){}
    AutoPtr(AutoPtr& other):m_data(other.release()){}
    ~AutoPtr(){
        if(m_data != nullptr){
            delete m_data;
            m_data = nullptr;
        }
    }

    T* get(){
        return m_data;
    }

    //对象所有权被转移，对象本身不占有该指针
    T* release(){
        auto data = m_data;
        m_data = nullptr;
        return data;
    }

    //赋值新指针
    void reset(T* data = nullptr){
        if(m_data != data){
            delete m_data;
            m_data = data;
        }
    }

    T* operator -> (){
        return m_data;
    } 
    T& operator * (){
        return *m_data;
    } 

    AutoPtr& operator = (AutoPtr<T>& other){
        if(this == &other){
            return *this;
        }
        m_data = other.relase();
        return *this;
    }

private:
    T* m_data;
};

class Test{
public:
    Test() = default;
    ~Test(){
        std::cout<<"test is deleted"<<std::endl;
    }
    void name(const string& name){
        m_name = name;
    }
    string name() const{
        return m_name;
    }

private:
    string m_name;
};

int main(){

    auto p = new Test();
    AutoPtr<Test> ap(p);
    //print:test is deleted
    p->name("jack");
    cout<<p->name()<<endl;
    ap->name("tom");
    cout<<ap->name()<<endl;

    AutoPtr<Test> ap2(ap);  //所有权转移
    std::cout<<ap2->name()<<endl;

    AutoPtr<Test> ap3 = ap2;  //所有权转移
    std::cout<<ap3->name()<<endl;;

    return 0;
}